package com.kotlin.demo.net

import com.kotlin.demo.net.OkHttpUtil.HttpCallBack
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.RequestBody
import java.io.*
import java.net.HttpURLConnection
import java.net.MalformedURLException
import java.net.URL
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.util.*

/**
 * 网络请求工具类
 */
object HttpManager {
    const val TAG = "HttpManager"

    /**
     * 获取发票号
     */
    fun getInvoiceNo(vmcNo: String, orderNo: String, httpCallBack: HttpCallBack?) {
        val timestamp = System.currentTimeMillis().toString() + ""
        val nonce = getRandomString(16) //16位随机码
        val apisec = str2MD5(vmcNo) //签名密钥
        val sign_str = ("apisec=" + apisec + "&" + "timestamp=" + timestamp + "&" + "nonce=" + nonce + "&" + "vmc_no="
                + vmcNo + "&" + "order_no=" + orderNo)
        val sign = str2MD5(sign_str)
        val params = ("timestamp=" + timestamp + "&" + "nonce=" + nonce + "&" + "vmc_no="
                + vmcNo + "&" + "order_no=" + orderNo + "&" + "sign=" + sign)
        println("ProductFinishFragment:$params")
        OkHttpUtil.get(OkHttpUtil.BASE_URL + "/getInvoice?" + params, httpCallBack)
    }

    fun str2MD5(str: String): String? {
        val md5: MessageDigest
        md5 = try {
            MessageDigest.getInstance("MD5")
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }
        //将字符串转换成字符串数组
        val pswdArray = str.toCharArray()
        val pswdByte = ByteArray(pswdArray.size)
        //将字符转换成字节
        for (i in pswdArray.indices) {
            pswdByte[i] = pswdArray[i].code.toByte()
        }
        val digest = md5.digest(pswdByte)
        //将得到的字节数组转换成十六进制数
        val buff = StringBuffer()
        for (i in digest.indices) {
            val num = digest[i].toInt() and 0xff
            //如果不足16，加0填充
            if (num < 16) buff.append("0")
            buff.append(Integer.toHexString(num))
        }
        return buff.toString()
    }

    /**
     * 生成随机数
     *
     * @param length 随机数长度
     * @return 随机数
     */
    fun getRandomString(length: Int): String {
        val str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        val random = Random()
        val sb = StringBuilder()
        for (i in 0 until length) {
            val number = random.nextInt(62)
            sb.append(str[number])
        }
        return sb.toString()
    }

    /**
     * 上传发票信息
     */
    @Throws(MalformedURLException::class)
    fun uploadInvoiceNo(
        vmcNo: String,
        orderNo: String,
        invoice_no: String?,
        body: String?,
        httpCallBack: HttpCallBack?
    ) {
        val timestamp = System.currentTimeMillis().toString() + ""
        val nonce = getRandomString(16) //16位随机码
        val apisec = str2MD5(vmcNo) //签名密钥
        val sign_str = ("apisec=" + apisec + "&" + "timestamp=" + timestamp + "&" + "nonce=" + nonce + "&" + "vmc_no="
                + vmcNo + "&" + "order_no=" + orderNo)
        val sign = str2MD5(sign_str)
        val params = ("timestamp=" + timestamp + "&" + "nonce=" + nonce + "&" + "vmc_no="
                + vmcNo + "&" + "order_no=" + orderNo + "&" + "sign=" + sign)
        println("ProductFinishFragment上传发票请求:$params")
        val requestBody: RequestBody = FormBody.Builder()
            .add("timestamp", timestamp)
            .add("nonce", nonce)
            .add("vmc_no", vmcNo)
            .add("apisec", apisec ?: "")
            .add("sign", sign ?: "")
            .add("invoice_no", invoice_no)
            .add("body", body)
            .build()
        OkHttpUtil.post(OkHttpUtil.BASE_URL + "/postInvoice?" + params, requestBody, httpCallBack)

//        StringBuilder bodyForm = new StringBuilder();
//// 表单参数与get形式一样
//        bodyForm.append("timestamp").append("=").append(timestamp).append("&")
//                .append("body").append("=").append(body).append("&")
//                .append("invoice_no").append("=").append(invoice_no).append("&")
//                .append("nonce").append("=").append(nonce).append("&")
//                .append("sign").append("=").append(sign == null ? "" : sign).append("&")
//                .append("apisec").append("=").append( apisec == null ? "" : apisec).append("&")
//                .append("vmc_no").append("=").append(vmc_no);
//        System.out.println("表单提交：" + bodyForm);
//        testPost(OkHttpUtil.BASE_URL + "/postInvoice?" + params, bodyForm.toString());
    }

    /**
     * 获取电子发票
     */
    fun getQrTicket(body: String?, httpCallBack: HttpCallBack?) {
        val JSON = MediaType.parse("application/json;charset=utf-8")
        val CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded")
        val requestBody: RequestBody = FormBody.Builder()
            .add("data", body).build()
        OkHttpUtil.post(" https://tc.168egg.com/tc-einvoice/data-entry.php", requestBody, httpCallBack)
    }

    /**
     * 注销电子发票
     */
    fun cancelTicket(body: String, httpCallBack: HttpCallBack?) {
        val requestBody: RequestBody = FormBody.Builder()
            .build()
        OkHttpUtil.post("https://einvoice.bjic.com.tw/Post/C0701?$body", requestBody, httpCallBack)
    }

    /**
     * 获取电子发票
     */
    fun checkInvoiceCode(code: String?, httpCallBack: HttpCallBack?) {
        val requestBody: RequestBody = FormBody.Builder()
            .add("code", code).build()
        OkHttpUtil.post("https://www.touch-cafe.com/tc-einvoice/code-query.php", requestBody, httpCallBack)
    }
    /**
     * 获取电子发票
     */
    fun get(code: String?, httpCallBack: HttpCallBack?) {
        val requestBody: RequestBody = FormBody.Builder()
            .add("code", code).build()
        OkHttpUtil.post("https://www.touch-cafe.com/tc-einvoice/code-query.php", requestBody, httpCallBack)
    }
    /**
     * 查询电子发票上传情况
     */
    fun queryQrTicketStatus(invoice: String?, httpCallBack: HttpCallBack?) {
        val requestBody: RequestBody = FormBody.Builder()
            .add("data", invoice).build()
        OkHttpUtil.post(" https://tc.168egg.com/tc-einvoice/data-query.php", requestBody, httpCallBack)
    }

    fun sendPost(urlStr: String?, dataStr: String) {
        var result = ""
        try {
            val data = dataStr.toByteArray(StandardCharsets.UTF_8)
            val url = URL(urlStr)
            val conn = url.openConnection() as HttpURLConnection
            conn.doOutput = true
            conn.doInput = true
            conn.useCaches = false
            conn.requestMethod = "POST"
            conn.setRequestProperty("Connection", "Keep-Alive")
            conn.setRequestProperty("Charset", "UTF-8")
            conn.setRequestProperty("Content-Length", data.size.toString())
            conn.setRequestProperty("Content-Type", "text/xml")
            //            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect()
            val out = DataOutputStream(conn.outputStream)
            //            OutputStream out = conn.getOutputStream();
            out.write(data)
            out.flush()
            out.close()
            println(conn.responseCode)
            if (conn.responseCode == 200) {
                println("连接成功")
                val `in` = conn.inputStream
                val data1 = readInputStream(`in`)
                result = String(data1)
                println("连接成功：$result")
            } else {
                println("连接失败")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    @Throws(MalformedURLException::class)
    fun testPost(urlStr: String?, dataStr: String?) {
        // Set the URL of the form endpoint
        try {
            val url = URL(urlStr)

            // Open a connection to the URL using HttpURLConnection
            val con = url.openConnection() as HttpURLConnection

            // Set the request method to POST
            con.requestMethod = "POST"

            // Set the content type of the request to form data
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")

            // Enable output for the connection
            con.doOutput = true

            // Create a data output stream to write the form data to the connection
            val out = DataOutputStream(con.outputStream)

            // Encode the form data and write it to the output stream
//            String formData = "name=" + URLEncoder.encode("John Smith", "UTF-8") + "&email=" + URLEncoder.encode("john.smith@example.com", "UTF-8");
            out.writeBytes(dataStr)

            // Close the output stream
            out.flush()
            out.close()

            // Read the response from the server
            val `in` = BufferedReader(InputStreamReader(con.inputStream))
            var inputLine: String?
            val response = StringBuffer()
            while (`in`.readLine().also { inputLine = it } != null) {
                response.append(inputLine)
            }
            `in`.close()

            // Print the response from the server
            println(response.toString())
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    @Throws(Exception::class)
    fun readInputStream(inStream: InputStream): ByteArray {
        val outStream = ByteArrayOutputStream()
        val buffer = ByteArray(10240)
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        var len = 0
        while (inStream.read(buffer).also { len = it } != -1) {
            outStream.write(buffer, 0, len)
        }
        inStream.close()
        return outStream.toByteArray()
    }
}